// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司 
// SPDX-License-Identifier: GPL-3.0-only 

import { clear_unread, get_unread_count, list_after, list_before, type MsgInfo } from "$lib/api/board/board_chat";
import { get_user_session } from "$lib/api/user";
import { request } from "$lib/utils/request";
import type { AllNotice, board as board_notice } from '$lib/api/notice_type';
import { emit } from "@tauri-apps/api/event";

class ChatStore {
    private _boardId = "";
    private _drawId = "";

    public msgList: MsgInfo[] = $state([]);
    public unreadCount = $state(0);
    private _lastMsgId = "";
    private _inListMsg = false;

    public showChat = $state(true);
    public autoScroll = $state(false);
    public scrollToMsgId = $state("");

    async init(boardId: string, drawId: string) {
        if (this._drawId == drawId) {
            return;
        }
        this._boardId = boardId;
        this._drawId = drawId;
        this.msgList = [];
        this.unreadCount = 0;
        this._lastMsgId = "";
        this.autoScroll = false;
        this.scrollToMsgId = "";
        await this.loadUnreadCount();
    }

    private async loadUnreadCount() {
        const sessionId = await get_user_session();
        const res = await request(
            get_unread_count({
                session_id: sessionId,
                board_id: this._boardId,
                draw_id: this._drawId,
            }),
        );
        this.unreadCount = res.unread_count;
    }

    private async doListMsgBefore() {
        let cmpMsgId = "";
        if (this.msgList.length > 0) {
            cmpMsgId = this.msgList[0].msg_id;
        }
        const sessionId = await get_user_session();
        const res = await request(list_before({
            session_id: sessionId,
            board_id: this._boardId,
            draw_id: this._drawId,
            msg_id: cmpMsgId,
            limit: 10,
        }));
        this._lastMsgId = res.last_msg_id;
        if (cmpMsgId != "" && res.msg_list.length > 0) {
            this.scrollToMsgId = cmpMsgId;
        }
        const tmpList = res.msg_list.slice();
        for (const msg of this.msgList) {
            const index = tmpList.findIndex(item => item.msg_id == msg.msg_id);
            if (index == -1) {
                tmpList.push(msg);
            }
        }
        if (tmpList.map(item => item.msg_id).includes(res.last_msg_id)) {
            await request(clear_unread({
                session_id: sessionId,
                board_id: this._boardId,
                draw_id: this._drawId,
            }));
            this.unreadCount = 0;
            const notice: AllNotice = {
                ClientNotice: {
                    ClearDrawMsgReadStateNotice: {
                        board_id: this._boardId,
                        draw_id: this._drawId,
                    },
                },
            };
            emit("notice", notice);
        }
        while (tmpList.length > 60) {
            tmpList.pop();
        }
        this.msgList = tmpList;
    }

    private async doListMsgAfter() {
        if (this.msgList.length == 0) {
            return;
        }
        const cmpMsgId = this.msgList[this.msgList.length - 1].msg_id;
        const sessionId = await get_user_session();
        const res = await request(list_after({
            session_id: sessionId,
            board_id: this._boardId,
            draw_id: this._drawId,
            msg_id: cmpMsgId,
            limit: 10,
        }));
        this._lastMsgId = res.last_msg_id;
        const tmpList = this.msgList.slice();
        for (const msg of res.msg_list) {
            const index = tmpList.findIndex(item => item.msg_id == msg.msg_id);
            if (index == -1) {
                tmpList.push(msg);
            }
        }
        if (tmpList.map(item => item.msg_id).includes(res.last_msg_id)) {
            await request(clear_unread({
                session_id: sessionId,
                board_id: this._boardId,
                draw_id: this._drawId,
            }));
            this.unreadCount = 0;
            const notice: AllNotice = {
                ClientNotice: {
                    ClearDrawMsgReadStateNotice: {
                        board_id: this._boardId,
                        draw_id: this._drawId,
                    },
                },
            };
            emit("notice", notice);
        }
        while (tmpList.length > 60) {
            tmpList.shift();
        }
        this.msgList = tmpList;
        if (this.autoScroll && this.msgList.length > 0) {
            this.scrollToMsgId = this.msgList[this.msgList.length - 1].msg_id;
        }
    }

    async listMsgBefore() {
        if (this._inListMsg) {
            return;
        }
        try {
            this._inListMsg = true;
            await this.doListMsgBefore();
        } finally {
            this._inListMsg = false;
        }
    }

    async listMsgAfter() {
        if (this._inListMsg) {
            return;
        }
        try {
            this._inListMsg = true;
            await this.doListMsgAfter();
        } finally {
            this._inListMsg = false;
        }
    }

    async processBoardNotice(notice: board_notice.AllNotice) {
        if (notice.NewChatMsgNotice != undefined && notice.NewChatMsgNotice.draw_id == this._drawId) {
            await this.loadUnreadCount();
            if (this.showChat) {
                if (this._lastMsgId == "") {
                    await this.listMsgBefore();
                } else {
                    const index = this.msgList.findIndex(item => item.msg_id == this._lastMsgId);
                    if (index != -1) {
                        await this.listMsgAfter();
                    }
                }
            }
        }
    }
}

export const chatStore = $state(new ChatStore());